package com.google.code.mircle.core.player;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.net.URL;

import javax.swing.JPanel;
import javax.swing.JProgressBar;

import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;

import com.google.code.mircle.App;
import com.google.code.mircle.core.Core;
import com.google.code.mircle.core.View;
import com.sun.jna.NativeLibrary;
import com.sun.jna.platform.FileUtils;

public class PlayerView extends JPanel implements View {

    PlayerPlugin s;

    EmbeddedMediaPlayerComponent media;

    App app;

    // current file
    File f;
    // current position
    float p;

    boolean statePaused = false;

    Object lock = new Object();
    JProgressBar progress = new JProgressBar();
    boolean counting;
    Thread progressCountringThread;

    public PlayerView(App core, PlayerPlugin s) {
        super(new BorderLayout());

        this.app = core;
        this.s = s;

        // path to target/classes or path/to/mircle.jar
        File f = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath());
        // path to target/
        f = f.getParentFile();
        // path to target/natives
        f = org.apache.commons.io.FileUtils.getFile(f, "natives");
        
        NativeLibrary.addSearchPath("vlc", f.getPath());

        addPlayer();
    }

    void addPlayer() {
        media = new EmbeddedMediaPlayerComponent();
        media.getMediaPlayer().setVolume(200);

        media.setMinimumSize(new Dimension(0, 0));
        add(media, BorderLayout.CENTER);

        final Canvas mouseEventsCanvas;
        mouseEventsCanvas = media.getVideoSurface();

        mouseEventsCanvas.addMouseListener(new MouseListener() {
            @Override
            public void mouseReleased(MouseEvent arg0) {
            }

            @Override
            public void mousePressed(MouseEvent arg0) {
            }

            @Override
            public void mouseExited(MouseEvent arg0) {
            }

            @Override
            public void mouseEntered(MouseEvent arg0) {
            }

            @Override
            public void mouseClicked(MouseEvent arg0) {
                mouseEventsCanvas.requestFocus();

                if (arg0.getClickCount() == 2) {
                    app.toggleFullScreen();
                }
            }
        });

        mouseEventsCanvas.addMouseMotionListener(new MouseMotionListener() {

            @Override
            public void mouseMoved(MouseEvent arg0) {
            }

            @Override
            public void mouseDragged(MouseEvent arg0) {
            }
        });

        mouseEventsCanvas.requestFocus();
        mouseEventsCanvas.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent arg0) {
            }

            @Override
            public void keyReleased(KeyEvent arg0) {
            }

            @Override
            public void keyPressed(KeyEvent arg0) {
                if (arg0.getKeyCode() == KeyEvent.VK_ESCAPE)
                    app.offFullScreen();

                if (arg0.getKeyCode() == KeyEvent.VK_SPACE) {
                    pause();
                }
            }
        });

        progress.setMinimum(0);
        progress.setMaximum(1000);
        progress.setStringPainted(true);
        progress.addMouseListener(new MouseListener() {

            @Override
            public void mouseReleased(MouseEvent arg0) {
            }

            @Override
            public void mousePressed(MouseEvent arg0) {
            }

            @Override
            public void mouseExited(MouseEvent arg0) {
            }

            @Override
            public void mouseEntered(MouseEvent arg0) {
            }

            @Override
            public void mouseClicked(MouseEvent arg0) {
                float f = arg0.getPoint().x / (float) progress.getWidth();
                media.getMediaPlayer().setPosition(f);

                mouseEventsCanvas.requestFocus();
            }
        });

        add(progress, BorderLayout.SOUTH);

        revalidate();
    }

    void start() {
        if (progressCountringThread == null || !progressCountringThread.isAlive()) {
            counting = true;
            progressCountringThread = new Thread(new Runnable() {

                @Override
                public void run() {
                    while (true) {

                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                        }

                        synchronized (lock) {
                            if (!counting)
                                break;

                            Core.invoke(new Runnable() {
                                @Override
                                public void run() {
                                    progress.setValue((int) (media.getMediaPlayer().getPosition() * 1000));

                                    if (!counting)
                                        return;

                                    if (!statePaused && !media.getMediaPlayer().isPlaying()) {
                                        media.getMediaPlayer().stop();
                                        stop();
                                    }
                                }
                            });
                        }
                    }
                }
            });
            progressCountringThread.start();
        }
    }

    void stop() {
        synchronized (lock) {
            counting = false;
        }
    }

    void play() {
        if (f != null)
            play(f);
    }

    void pause() {
        statePaused = !statePaused;

        if (statePaused)
            media.getMediaPlayer().pause();
        else
            media.getMediaPlayer().play();
    }

    public void play(File file) {
        start();

        f = file;
        media.getMediaPlayer().prepareMedia(f.toString());
        media.getMediaPlayer().play();
        media.getMediaPlayer().setPosition(p);
    }
}
